home *** CD-ROM | disk | FTP | other *** search
- #include <Palettes.h>
- #include <LoMem.h>
-
- #include <StuTypes.h>
-
- #pragma parameter __A0 RegA5() // MOVEA.L A5,A0
- local Handle RegA5(void) = { 0x204D };
-
- typedef struct { short number; Rect r[]; } nrct;
- typedef struct { Ptr baseAddr; short rowBytes; long topleft; long botright; } BMTemplate;
-
- void fix_bitmap(BitMap *bm, Ptr newbase, short newright);
- void fix_grafport(GrafPtr gp, Ptr newbase, short newright);
-
- export void main(void)
- {
- QDGlobals *qdglobptr = (QDGlobals *)(*RegA5() - sizeof(QDGlobals) + sizeof(GrafPtr));
- nrct **rh = (nrct **)GetResource('nrct', 0); // Read configuration
- GDPtr gdevp = GetMainDevice()[0]; // Get the main screen device
- PixMapPtr pm = gdevp->gdPMap[0]; // And get its pixmap
- // Decide what multiple to round pixel count to (to preserve byte alignment)
- short pixel_mask = (pm->pixelSize >= 8) ? 0 : (8 / pm->pixelSize - 1);
- // pixels cut from left edge
- short trim_l = (rh[0]->r[0].left + pixel_mask) & ~pixel_mask;
- short pixels_cut = trim_l + rh[0]->r[0].right; // Total pixels cut
- long byte_shift = trim_l * pm->pixelSize / 8; // Offset to add to baseAddr
- Ptr newbase = pm->baseAddr + byte_shift;
- short newright = pm->bounds.right - pixels_cut;
- WindowPeek wp = WindowList;
- register BMTemplate *bm = NULL;
- register Ptr oldbase = pm->baseAddr;
- register long oldtopleft = *(long*)(&pm->bounds.top);
- register long oldbotright = *(long*)(&pm->bounds.bottom);
-
- //Debugger();
- ScrnBase = newbase; // Update the ScrnBase lomem variable
- gdevp->gdRect.right = newright; // Fix the gdRect of the main device
- CrsrPin.right = newright; // Update the cursor limit rect
-
- // If an A5 world is set up, fix the screenBits variable
- if (qdglobptr->screenBits.baseAddr == pm->baseAddr)
- fix_bitmap(&qdglobptr->screenBits, newbase, newright);
- fix_bitmap((BitMap*)pm, newbase, newright); // Fix the main device's pixmap
- fix_grafport(WMgrPort, newbase, newright); // Fix the window manager (desktop) ports
- fix_grafport((GrafPtr)WMgrCPort, newbase, newright);
- while (wp) // Fix any open windows
- {
- fix_grafport(&wp->port, newbase, newright);
- wp=wp->nextWindow;
- }
-
- // Damn! After all this, it still doesn't work. Do an exhaustive search of all
- // memory, finding all BitMaps which look like copies of screenBits, and fix them.
- while ((Ptr)bm < BufPtr)
- {
- if (bm->baseAddr == oldbase &&
- bm->topleft == oldtopleft &&
- bm->botright == oldbotright)
- fix_bitmap((BitMap *)bm, newbase, newright);
- bm = (BMTemplate*)((Ptr)bm+2);
- }
-
- {
- int i = 0;
- long rowbytes = pm->rowBytes & 0x3FFF;
- Ptr p = oldbase;
- while (i<pm->bounds.bottom)
- {
- int j;
- Ptr pp = p;
- for (j=0; j<byte_shift; j++) *pp++ = 0xFF;
- p += rowbytes;
- i++;
- }
- }
-
- }
-
- void fix_bitmap(BitMap *bm, Ptr newbase, short newright)
- {
- // Check if this is actually the PixMapHandle of a CGrafPort
- if ((bm->rowBytes & 0xC000) == 0xC000) bm = (BitMap *)*(bm->baseAddr);
- bm->baseAddr = newbase;
- bm->bounds.right = newright;
- }
-
- void fix_grafport(GrafPtr gp, Ptr newbase, short newright)
- {
- fix_bitmap(&gp->portBits, newbase, newright);
- gp->portRect.right = newright;
- }
-